{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "+++\n",
    "title = \"Multiple factor analysis\"\n",
    "menu = \"main\"\n",
    "weight = 4\n",
    "toc = true\n",
    "aliases = [\"mfa\"]\n",
    "+++"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Resources"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [Multiple Factor Analysis](https://www.utdallas.edu/~herve/Abdi-MFA2007-pretty.pdf)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data\n",
    "\n",
    "Multiple factor analysis (MFA) is meant to be used when you have groups of variables. In practice, it builds a PCA on each group. It then fits a global PCA on the results of the so-called partial PCAs.\n",
    "\n",
    "The dataset used in the following example come from [this paper](https://www.utdallas.edu/~herve/Abdi-MFA2007-pretty.pdf). In the dataset, three experts give their opinion on six different wines. Each opinion for each wine is recorded as a variable. We thus want to consider the separate opinions of each expert whilst also having a global overview of each wine. MFA is the perfect fit for this kind of situation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-07T18:18:06.723525Z",
     "iopub.status.busy": "2024-09-07T18:18:06.722844Z",
     "iopub.status.idle": "2024-09-07T18:18:07.156896Z",
     "shell.execute_reply": "2024-09-07T18:18:07.156597Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th>expert</th>\n",
       "      <th>Oak type</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Expert 1</th>\n",
       "      <th colspan=\"4\" halign=\"left\">Expert 2</th>\n",
       "      <th colspan=\"3\" halign=\"left\">Expert 3</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>aspect</th>\n",
       "      <th></th>\n",
       "      <th>Fruity</th>\n",
       "      <th>Woody</th>\n",
       "      <th>Coffee</th>\n",
       "      <th>Red fruit</th>\n",
       "      <th>Roasted</th>\n",
       "      <th>Vanillin</th>\n",
       "      <th>Woody</th>\n",
       "      <th>Fruity</th>\n",
       "      <th>Butter</th>\n",
       "      <th>Woody</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Wine 1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>7</td>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "      <td>7</td>\n",
       "      <td>6</td>\n",
       "      <td>3</td>\n",
       "      <td>6</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 2</th>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "      <td>2</td>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 3</th>\n",
       "      <td>2</td>\n",
       "      <td>6</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 4</th>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>7</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 5</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "      <td>5</td>\n",
       "      <td>6</td>\n",
       "      <td>5</td>\n",
       "      <td>2</td>\n",
       "      <td>6</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 6</th>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "      <td>3</td>\n",
       "      <td>5</td>\n",
       "      <td>4</td>\n",
       "      <td>5</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "expert Oak type Expert 1               Expert 2                          \n",
       "aspect            Fruity Woody Coffee Red fruit Roasted Vanillin Woody   \n",
       "Wine 1        1        1     6      7         2       5        7     6  \\\n",
       "Wine 2        2        5     3      2         4       4        4     2   \n",
       "Wine 3        2        6     1      1         5       2        1     1   \n",
       "Wine 4        2        7     1      2         7       2        1     2   \n",
       "Wine 5        1        2     5      4         3       5        6     5   \n",
       "Wine 6        1        3     4      4         3       5        4     5   \n",
       "\n",
       "expert Expert 3               \n",
       "aspect   Fruity Butter Woody  \n",
       "Wine 1        3      6     7  \n",
       "Wine 2        4      4     3  \n",
       "Wine 3        7      1     1  \n",
       "Wine 4        2      2     2  \n",
       "Wine 5        2      6     6  \n",
       "Wine 6        1      7     5  "
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import prince \n",
    "\n",
    "dataset = prince.datasets.load_burgundy_wines()\n",
    "dataset"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fitting"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The groups are passed as a dictionary to the `fit` method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-07T18:18:07.158550Z",
     "iopub.status.busy": "2024-09-07T18:18:07.158412Z",
     "iopub.status.idle": "2024-09-07T18:18:07.168474Z",
     "shell.execute_reply": "2024-09-07T18:18:07.168190Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Expert 1', 'Expert 2', 'Expert 3']"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "groups = dataset.columns.levels[0].drop(\"Oak type\").tolist()\n",
    "groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-07T18:18:07.170307Z",
     "iopub.status.busy": "2024-09-07T18:18:07.170203Z",
     "iopub.status.idle": "2024-09-07T18:18:07.196303Z",
     "shell.execute_reply": "2024-09-07T18:18:07.195199Z"
    }
   },
   "outputs": [],
   "source": [
    "mfa = prince.MFA(\n",
    "    n_components=2,\n",
    "    n_iter=3,\n",
    "    copy=True,\n",
    "    check_input=True,\n",
    "    engine='sklearn',\n",
    "    random_state=42\n",
    ")\n",
    "mfa = mfa.fit(dataset, groups=groups)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Eigenvalues"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-07T18:18:07.205973Z",
     "iopub.status.busy": "2024-09-07T18:18:07.205530Z",
     "iopub.status.idle": "2024-09-07T18:18:07.257203Z",
     "shell.execute_reply": "2024-09-07T18:18:07.255559Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>eigenvalue</th>\n",
       "      <th>% of variance</th>\n",
       "      <th>% of variance (cumulative)</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>component</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2.835</td>\n",
       "      <td>88.82%</td>\n",
       "      <td>88.82%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.357</td>\n",
       "      <td>11.18%</td>\n",
       "      <td>100.00%</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          eigenvalue % of variance % of variance (cumulative)\n",
       "component                                                    \n",
       "0              2.835        88.82%                     88.82%\n",
       "1              0.357        11.18%                    100.00%"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mfa.eigenvalues_summary"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Coordinates"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `MFA` inherits from the `PCA` class, which means it provides access to the `PCA` methods and properties. For instance, the `row_coordinates` method will return the global coordinates of each wine."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-07T18:18:07.266647Z",
     "iopub.status.busy": "2024-09-07T18:18:07.265730Z",
     "iopub.status.idle": "2024-09-07T18:18:07.286132Z",
     "shell.execute_reply": "2024-09-07T18:18:07.285239Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Wine 1</th>\n",
       "      <td>-2.172155</td>\n",
       "      <td>-0.508596</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 2</th>\n",
       "      <td>0.557017</td>\n",
       "      <td>-0.197408</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 3</th>\n",
       "      <td>2.317663</td>\n",
       "      <td>-0.830259</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 4</th>\n",
       "      <td>1.832557</td>\n",
       "      <td>0.905046</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 5</th>\n",
       "      <td>-1.403787</td>\n",
       "      <td>0.054977</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 6</th>\n",
       "      <td>-1.131296</td>\n",
       "      <td>0.576241</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               0         1\n",
       "Wine 1 -2.172155 -0.508596\n",
       "Wine 2  0.557017 -0.197408\n",
       "Wine 3  2.317663 -0.830259\n",
       "Wine 4  1.832557  0.905046\n",
       "Wine 5 -1.403787  0.054977\n",
       "Wine 6 -1.131296  0.576241"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mfa.row_coordinates(dataset)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, all the other methods are not implemented yet. They will raise a `NotImplemented` exception if you call them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-07T18:18:07.290866Z",
     "iopub.status.busy": "2024-09-07T18:18:07.290496Z",
     "iopub.status.idle": "2024-09-07T18:18:07.320729Z",
     "shell.execute_reply": "2024-09-07T18:18:07.319946Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th>group</th>\n",
       "      <th colspan=\"2\" halign=\"left\">Expert 1</th>\n",
       "      <th colspan=\"2\" halign=\"left\">Expert 2</th>\n",
       "      <th colspan=\"2\" halign=\"left\">Expert 3</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>component</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Wine 1</th>\n",
       "      <td>-2.764432</td>\n",
       "      <td>-1.104812</td>\n",
       "      <td>-2.213928</td>\n",
       "      <td>-0.863519</td>\n",
       "      <td>-1.538106</td>\n",
       "      <td>0.442545</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 2</th>\n",
       "      <td>0.773034</td>\n",
       "      <td>0.298919</td>\n",
       "      <td>0.284247</td>\n",
       "      <td>-0.132135</td>\n",
       "      <td>0.613771</td>\n",
       "      <td>-0.759009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 3</th>\n",
       "      <td>1.991398</td>\n",
       "      <td>0.805893</td>\n",
       "      <td>2.111508</td>\n",
       "      <td>0.499718</td>\n",
       "      <td>2.850084</td>\n",
       "      <td>-3.796390</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 4</th>\n",
       "      <td>1.981456</td>\n",
       "      <td>0.927187</td>\n",
       "      <td>2.393009</td>\n",
       "      <td>1.227146</td>\n",
       "      <td>1.123206</td>\n",
       "      <td>0.560803</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 5</th>\n",
       "      <td>-1.292834</td>\n",
       "      <td>-0.620661</td>\n",
       "      <td>-1.492114</td>\n",
       "      <td>-0.488088</td>\n",
       "      <td>-1.426414</td>\n",
       "      <td>1.273679</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 6</th>\n",
       "      <td>-0.688623</td>\n",
       "      <td>-0.306527</td>\n",
       "      <td>-1.082723</td>\n",
       "      <td>-0.243122</td>\n",
       "      <td>-1.622541</td>\n",
       "      <td>2.278372</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "group      Expert 1            Expert 2            Expert 3          \n",
       "component         0         1         0         1         0         1\n",
       "Wine 1    -2.764432 -1.104812 -2.213928 -0.863519 -1.538106  0.442545\n",
       "Wine 2     0.773034  0.298919  0.284247 -0.132135  0.613771 -0.759009\n",
       "Wine 3     1.991398  0.805893  2.111508  0.499718  2.850084 -3.796390\n",
       "Wine 4     1.981456  0.927187  2.393009  1.227146  1.123206  0.560803\n",
       "Wine 5    -1.292834 -0.620661 -1.492114 -0.488088 -1.426414  1.273679\n",
       "Wine 6    -0.688623 -0.306527 -1.082723 -0.243122 -1.622541  2.278372"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mfa.group_row_coordinates(dataset)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-07T18:18:07.324369Z",
     "iopub.status.busy": "2024-09-07T18:18:07.323686Z",
     "iopub.status.idle": "2024-09-07T18:18:07.390142Z",
     "shell.execute_reply": "2024-09-07T18:18:07.375560Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<div id=\"altair-viz-d92c253af44d4d43b001c1af30e4f2cb\"></div>\n",
       "<script type=\"text/javascript\">\n",
       "  var VEGA_DEBUG = (typeof VEGA_DEBUG == \"undefined\") ? {} : VEGA_DEBUG;\n",
       "  (function(spec, embedOpt){\n",
       "    let outputDiv = document.currentScript.previousElementSibling;\n",
       "    if (outputDiv.id !== \"altair-viz-d92c253af44d4d43b001c1af30e4f2cb\") {\n",
       "      outputDiv = document.getElementById(\"altair-viz-d92c253af44d4d43b001c1af30e4f2cb\");\n",
       "    }\n",
       "    const paths = {\n",
       "      \"vega\": \"https://cdn.jsdelivr.net/npm//vega@5?noext\",\n",
       "      \"vega-lib\": \"https://cdn.jsdelivr.net/npm//vega-lib?noext\",\n",
       "      \"vega-lite\": \"https://cdn.jsdelivr.net/npm//vega-lite@4.17.0?noext\",\n",
       "      \"vega-embed\": \"https://cdn.jsdelivr.net/npm//vega-embed@6?noext\",\n",
       "    };\n",
       "\n",
       "    function maybeLoadScript(lib, version) {\n",
       "      var key = `${lib.replace(\"-\", \"\")}_version`;\n",
       "      return (VEGA_DEBUG[key] == version) ?\n",
       "        Promise.resolve(paths[lib]) :\n",
       "        new Promise(function(resolve, reject) {\n",
       "          var s = document.createElement('script');\n",
       "          document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "          s.async = true;\n",
       "          s.onload = () => {\n",
       "            VEGA_DEBUG[key] = version;\n",
       "            return resolve(paths[lib]);\n",
       "          };\n",
       "          s.onerror = () => reject(`Error loading script: ${paths[lib]}`);\n",
       "          s.src = paths[lib];\n",
       "        });\n",
       "    }\n",
       "\n",
       "    function showError(err) {\n",
       "      outputDiv.innerHTML = `<div class=\"error\" style=\"color:red;\">${err}</div>`;\n",
       "      throw err;\n",
       "    }\n",
       "\n",
       "    function displayChart(vegaEmbed) {\n",
       "      vegaEmbed(outputDiv, spec, embedOpt)\n",
       "        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));\n",
       "    }\n",
       "\n",
       "    if(typeof define === \"function\" && define.amd) {\n",
       "      requirejs.config({paths});\n",
       "      require([\"vega-embed\"], displayChart, err => showError(`Error loading script: ${err.message}`));\n",
       "    } else {\n",
       "      maybeLoadScript(\"vega\", \"5\")\n",
       "        .then(() => maybeLoadScript(\"vega-lite\", \"4.17.0\"))\n",
       "        .then(() => maybeLoadScript(\"vega-embed\", \"6\"))\n",
       "        .catch(showError)\n",
       "        .then(() => displayChart(vegaEmbed));\n",
       "    }\n",
       "  })({\"config\": {\"view\": {\"continuousWidth\": 400, \"continuousHeight\": 300}}, \"data\": {\"name\": \"data-f4702574ad2d439a52cddb98144a5bf4\"}, \"mark\": \"circle\", \"encoding\": {\"tooltip\": [{\"field\": \"index\", \"type\": \"nominal\"}, {\"field\": \"component 0\", \"type\": \"quantitative\"}, {\"field\": \"component 1\", \"type\": \"quantitative\"}], \"x\": {\"axis\": {\"title\": \"component 0 \\u2014 88.82%\"}, \"field\": \"component 0\", \"scale\": {\"zero\": false}, \"type\": \"quantitative\"}, \"y\": {\"axis\": {\"title\": \"component 1 \\u2014 11.18%\"}, \"field\": \"component 1\", \"scale\": {\"zero\": false}, \"type\": \"quantitative\"}}, \"selection\": {\"selector001\": {\"type\": \"interval\", \"bind\": \"scales\", \"encodings\": [\"x\", \"y\"]}}, \"$schema\": \"https://vega.github.io/schema/vega-lite/v4.17.0.json\", \"datasets\": {\"data-f4702574ad2d439a52cddb98144a5bf4\": [{\"index\": \"Wine 1\", \"component 0\": -2.1721551320488603, \"component 1\": -0.5085956412193768}, {\"index\": \"Wine 2\", \"component 0\": 0.5570172765758488, \"component 1\": -0.19740840358948095}, {\"index\": \"Wine 3\", \"component 0\": 2.317663316335471, \"component 1\": -0.8302594762332379}, {\"index\": \"Wine 4\", \"component 0\": 1.8325573279633347, \"component 1\": 0.9050455800200178}, {\"index\": \"Wine 5\", \"component 0\": -1.4037872883482334, \"component 1\": 0.054976713943079694}, {\"index\": \"Wine 6\", \"component 0\": -1.131295500477561, \"component 1\": 0.5762412270789976}]}}, {\"mode\": \"vega-lite\"});\n",
       "</script>"
      ],
      "text/plain": [
       "alt.Chart(...)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mfa.plot(\n",
    "    dataset,\n",
    "    x_component=0,\n",
    "    y_component=1\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first axis explains most of the difference between the wine ratings. This difference is actually due to the oak type of the barrels they were fermented in."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Partial PCAs"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "An MFA is essentially a PCA applied to the outputs of partial PCA. Indeed, a PCA is first fitted to each group. A partial PCA can be accessed as so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-07T18:18:07.395738Z",
     "iopub.status.busy": "2024-09-07T18:18:07.395414Z",
     "iopub.status.idle": "2024-09-07T18:18:07.415427Z",
     "shell.execute_reply": "2024-09-07T18:18:07.414138Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>aspect</th>\n",
       "      <th>Fruity</th>\n",
       "      <th>Woody</th>\n",
       "      <th>Coffee</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Wine 1</th>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 2</th>\n",
       "      <td>5</td>\n",
       "      <td>3</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 3</th>\n",
       "      <td>6</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 4</th>\n",
       "      <td>7</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 5</th>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wine 6</th>\n",
       "      <td>3</td>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "aspect  Fruity  Woody  Coffee\n",
       "Wine 1       1      6       7\n",
       "Wine 2       5      3       2\n",
       "Wine 3       6      1       1\n",
       "Wine 4       7      1       2\n",
       "Wine 5       2      5       4\n",
       "Wine 6       3      4       4"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset['Expert 1']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-09-07T18:18:07.419686Z",
     "iopub.status.busy": "2024-09-07T18:18:07.419388Z",
     "iopub.status.idle": "2024-09-07T18:18:07.438711Z",
     "shell.execute_reply": "2024-09-07T18:18:07.436939Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>eigenvalue</th>\n",
       "      <th>% of variance</th>\n",
       "      <th>% of variance (cumulative)</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>component</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2.863</td>\n",
       "      <td>95.42%</td>\n",
       "      <td>95.42%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.120</td>\n",
       "      <td>3.99%</td>\n",
       "      <td>99.41%</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          eigenvalue % of variance % of variance (cumulative)\n",
       "component                                                    \n",
       "0              2.863        95.42%                     95.42%\n",
       "1              0.120         3.99%                     99.41%"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mfa['Expert 1'].eigenvalues_summary"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  },
  "vscode": {
   "interpreter": {
    "hash": "441c2ec70d9faeb70e7723f55150c6260f4a26a9c828b90915d3399002e14f43"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
